perf: speed up testplane launch#1115
Conversation
commit: |
1fbdabb to
7838f1d
Compare
| "gemini-configparser": "1.4.1", | ||
| "get-port": "5.1.1", | ||
| "import-meta-resolve": "4.0.0", | ||
| "load-esm": "1.0.2", |
There was a problem hiding this comment.
Contains like 1 LOC:
module.exports = { loadEsm: (module) => import(module) };In our project, typescript compiles all "import" to "require" and we can't prevent it
So, this package is used
| export const MIN_CHROMIUM_VERSION = 73; | ||
| export const MIN_FIREFOX_VERSION = 60; | ||
| export const MIN_EDGEDRIVER_VERSION = 94; | ||
| export const DRIVER_WAIT_INTERVAL = 25; // 20ms |
There was a problem hiding this comment.
We are almost blocked while waiting for webdriver launch
Checking "if port is busy" more often saves some time by price of some CPU cycles
| } | ||
|
|
||
| async getBrowser(id: string, opts: BrowserOpts = {}): Promise<NewBrowser> { | ||
| const { NewBrowser } = await import("../browser/new-browser"); |
There was a problem hiding this comment.
"NewBrowser" takes some time to import
using lazy-load here (and in many other places) to reduce "time to require" and therefore - time to start workers, which is crucial
| @@ -1,4 +1,4 @@ | |||
| import { ImageInfo, RefImageInfo } from "../../../../types"; | |||
| import type { ImageInfo, RefImageInfo } from "../../../../types"; | |||
There was a problem hiding this comment.
"import" -> "import type" also saves some time
|
|
||
| saveDiffTo(diffPath: string): Promise<null> { | ||
| return Image.buildDiff({ diff: diffPath, ...this.diffOpts }); | ||
| return import("../../../../image").then(m => m.Image.buildDiff({ diff: diffPath, ...this.diffOpts })); |
There was a problem hiding this comment.
"Image" is fat, and we dont need to requrie "Image" module every time
| import { loadEsm } from "load-esm"; | ||
|
|
||
| export const preloadWebdriverIO = async (): Promise<void> => { | ||
| await loadEsm("@testplane/webdriverio").catch(() => {}); |
There was a problem hiding this comment.
require("@testplane/webdriverio") is cheap because it does not compile almost any of wdio code:
exports.remote = async function(params, remoteModifier) {
const { remote } = await import("./node.js");
return remote(params, remoteModifier);
};| preloadMochaReader(); | ||
| preloadTestTransformer(); | ||
| preloadWebdriverIO(); |
There was a problem hiding this comment.
worker has some spare time, before master didn't send "runTest" command
| register(workerFilepath, exportedMethods) { | ||
| this._workerFarm.loadModule(workerFilepath, _.noop); |
There was a problem hiding this comment.
before:
- "workerFilePath" is compiled only on call
after:
- "workerFilePath" is compiled on register, so method would be called earlier
| runner.prepareBrowser({ sessionId, sessionCaps, sessionOpts, state }); | ||
|
|
||
| const tests = await this._testParser.parse({ file, browserId }); |
There was a problem hiding this comment.
in worker, preparing browser does not depend on test
so we can start preparing browser before parsing test file
| this._test.testplaneCtx = _.cloneDeep(test.testplaneCtx) || {}; | ||
| } | ||
|
|
||
| async prepareBrowser({ sessionId, sessionCaps, sessionOpts, state }) { |
There was a problem hiding this comment.
floating promise, but does not throw
throws on "prepareToRun" with test and tool context to save compatibility
c30dd64 to
c1fd802
Compare
| const session = await WebDriver.newSession(fullSessionOpts); | ||
|
|
||
| const detectedSessionEnvFlags = sessionEnvironmentDetector({ | ||
| capabilities: session.capabilities, | ||
| requestedCapabilities: fullSessionOpts.capabilities, | ||
| }); | ||
|
|
||
| return attach({ |
There was a problem hiding this comment.
While we waiting webdriver session, webdriverio is being preloaded (preloading started after workers are created)
unfortunately, we have to use wdio even in master, because SESSION_START is emitted from master:
https://testplane.io/docs/v8/reference/testplane-events/#session_start
c1fd802 to
86a2e95
Compare
No description provided.